package com.chhuang.mongo.core.dao;

import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;

import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.mongodb.gridfs.GridFsTemplate;

import com.chhuang.mongo.core.bean.QueryBean;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSFile;

public class AbstractMongoDao<T> {
	
	public static final String KEY = "KeY";
	public static final String LIKE = ".*?KeY.*";
	public static final String NOT_EQUAL = "(?!KeY$).*";
	public static final String NOT_LIKE = "((?!KeY).)*";
	public static final String IGNORE_CASE = "i";
	public static final String ID = "_id";

	private Class<T> entityClass;
	protected Class<T> getEntityClass() {
		return entityClass;
	}

	/**
	 * 通过反射获取子类确定的泛型类
	 */
	@SuppressWarnings("unchecked")
	public AbstractMongoDao() {
		Type genType = getClass().getGenericSuperclass();
		Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
		entityClass = (Class<T>) params[0];
	}

	@Autowired
	protected MongoTemplate mongoTemplate;

	@Autowired
	protected GridFsTemplate gridFsTemplate;

	/**
	 * 保存
	 * 
	 * @param entity
	 * @return
	 */
	public void save(T entity) {
		mongoTemplate.insert(entity);
	}

	/**
	 * 保存或修改
	 * 
	 * @param entity
	 * @return
	 */
	public void saveOrUpdate(T entity) {
		mongoTemplate.save(entity);
	}

	/**
	 * 根据id删除一条数据
	 * 
	 * @param id
	 * @return
	 */
	public boolean deleteById(ObjectId id) {
		Query query = new Query();
		query.addCriteria(Criteria.where(ID).is(id));
		return !mongoTemplate.remove(query, entityClass).isUpdateOfExisting();
	}

	/**
	 * 删除一条数据
	 * 
	 * @param id
	 * @return
	 */
	public boolean delete(T t) {
		return !mongoTemplate.remove(t).isUpdateOfExisting();
	}
	
	/**
	 * 删除满足条件的所有记录
	 * 
	 * @param query
	 * @return
	 */
	public boolean delete(Query query) {
		return !mongoTemplate.remove(query, entityClass).isUpdateOfExisting();
	}
	
	/**
	 * 根据id更新一条记录
	 * 
	 * @param query
	 * @param update
	 */
	public boolean updateById(ObjectId id, Update update) {
		Query query = new Query();
		query.addCriteria(Criteria.where(ID).is(id));
		return mongoTemplate.updateFirst(query, update, entityClass).isUpdateOfExisting();
	}
	
	/**
	 * 更新满足条件的第一个记录
	 * 
	 * @param query
	 * @param update
	 */
	public boolean updateFirst(Query query, Update update) {
		return mongoTemplate.updateFirst(query, update, entityClass).isUpdateOfExisting();
	}

	/**
	 * 更新满足条件的所有记录
	 * 
	 * @param query
	 * @param update
	 */
	public boolean updateMulti(Query query, Update update) {
		return mongoTemplate.updateMulti(query, update, entityClass).isUpdateOfExisting();
	}

	/**
	 * 查找更新,如果没有找到符合的记录,则将更新的记录插入库中
	 * 
	 * @param query
	 * @param update
	 */
	public boolean updateInser(Query query, Update update) {
		return mongoTemplate.upsert(query, update, entityClass).isUpdateOfExisting();
	}

	/**
	 * 根据id查询一条数据
	 * 
	 * @param id
	 * @return
	 */
	public T findById(ObjectId id) {
		return mongoTemplate.findById(id, entityClass);
	}
	
	/**
	 * 查找满足条件的第一条记录
	 * 
	 * @param query
	 * @return
	 */
	public T findOne(Query query) {
		return mongoTemplate.findOne(query, entityClass);
	}
	
	/**
	 * 查找满足条件的集合
	 * 
	 * @param query
	 * @return
	 */
	public List<T> findList(Query query){
		return mongoTemplate.find(query, entityClass);
	}
	
	/**
	 * 分页查询
	 * 
	 * @param query
	 * @param start
	 * @param size
	 * @return
	 */
	public List<T> pagination(Query query, int start, int size) {
		query.skip(start);
		query.limit(size);
		return mongoTemplate.find(query, entityClass);
	}
	
	/**
	 * 统计数量
	 * 
	 * @param query
	 * @return
	 */
	public Long count(Query query) {
		return mongoTemplate.count(query, entityClass);
	}
	
	/**
	 * 分页查询
	 * 
	 * @param queryBean
	 * @return
	 */
	public QueryBean<T> pagination(QueryBean<T> queryBean) {
		Query query = queryBean.getQuery();
		long count = count(query);
		queryBean.setItemCount(count);
		if(count>0){
			int start = 0 ,size = 0;
			if (queryBean.getPageNum() > 0 && queryBean.getPageSize() > 0) {
				start = (queryBean.getPageNum() - 1) * queryBean.getPageSize();
				size = queryBean.getPageSize();
				queryBean.setPageCount(count / size + (count % size > 0 ? 1 : 0));
			}
			queryBean.setResults(pagination(query, start, size));
		}
		return queryBean;
	}
	
	/**
	 * 保存文件
	 * 
	 * @param content
	 * @param filename
	 * @return
	 */
	public GridFSFile saveFile(InputStream content, String filename,
			String contentType) {
		return gridFsTemplate.store(content, filename, contentType);
	}
	
	/**
	 * 根据id删除文件
	 * 
	 * @param query
	 */
	public void deleteFileById(Object id){
		Query query = new Query();
		query.addCriteria(Criteria.where(ID).is(id));
		gridFsTemplate.delete(query);
	}
	
	/**
	 * 删除满足条件的文件
	 * 
	 * @param query
	 */
	public void deleteFile(Query query){
		gridFsTemplate.delete(query);
	}

	/**
	 * 根据id查询文件
	 * 
	 * @param id
	 * @return
	 */
	public GridFSDBFile findFileById(Object id) {
		Query query = new Query();
		query.addCriteria(Criteria.where(ID).is(id));
		return gridFsTemplate.findOne(query);
	}
	
	/**
	 * 查询满足条件的第一个文件
	 * 
	 * @param query
	 * @return
	 */
	public GridFSDBFile findOneFile(Query query){
		return gridFsTemplate.findOne(query);
	}
	
	/**
	 * 查询满足条件的所有文件
	 * 
	 * @param query
	 * @return
	 */
	public List<GridFSDBFile> findFiles(Query query){
		return gridFsTemplate.find(query);
	}
}
